package crawler.web.framework;

import java.util.List;

import javax.annotation.Resource;

import library.Tracer;
import library.database.mongo.MongoDB;
import library.thread.flow.ParameterBox;
import library.thread.flow.WorkflowContainer;
import library.thread.flow.WorkflowNode;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import crawler.web.beans.CrawlPageContext;
import crawler.web.beans.PageFingerPrint;
import crawler.web.deduplicate.SimHashUtil;
import crawler.web.engine.config.SpBN;
import crawler.web.engine.config.Suite;
import crawler.web.engine.custom.MongoDBAdapter;
import crawler.web.utils.FingerPrintDPL;

/**
 * 在context2中查找相似的數據
 * 
 * @author waynechen Feb 8, 2012 11:18:01 PM
 */
@Component("AnalyzerSim")
@Scope(value = "prototype")
public class AnalyzerSim extends WorkflowNode {
	@Autowired(required = true)
	public AnalyzerSim(//
	@Value("#{T(crawler.web.framework.CrawlerContainer).getNO()}") String name, //
			@Qualifier("CrawlerContainer") WorkflowContainer<Crawler> container//
	) {
		super("AnalyzerSim " + name, container);
	}

	private int waitTimes = 0;

	@Resource(name = SpBN.bean_MongoDB)
	private MongoDB mongo;

	@Resource(name = "MongoDBAdapter")
	private MongoDBAdapter dbAdapter;

	@Resource(name = SpBN.bean_fingerprint_berkeleydb)
	private FingerPrintDPL simpleDPL;

	@Resource(name = SpBN.conf_table_empty_wait_time)
	private Integer waitTime;

	@Resource(name = SpBN.conf_parseTabName2)
	private String tableContext2;

	@Override
	protected void nodeExecute(ParameterBox args) {
		Tracer.info("线程: " + name + " 开始");

		int count = 0;
		try {
			while (true) {
				if (isStopped())
					break;

				//处理消息
				handleMessage();

				CrawlPageContext pageContext = dbAdapter.getNext(//
				tableContext2, Suite.ParseStatus.DEDUPLICATED, Suite.ParseStatus.FIND_SIMILAR_FINGER_PRINT);

				if (pageContext == null) {
					Tracer.info("分析库1中没有等待分析的数据,等待中...");
					sleepWithoutThrowing(10000);
					if (waitTimes++ > (waitTime / 10000))
						getContainer().sendMessage2me(this, WorkflowContainer.MSG_STOP_ALL_SUBNODES, null);
					continue;
				}
				waitTimes = 0;

				Tracer.trace("info", "执行到第%d条, id = %s, fp = %s", ++count, pageContext.get_id(), pageContext.getFingerPrint());

				//查找相似页面
				//计算出simHashList
				List<Long> simHashList = SimHashUtil.getSimHashList(pageContext.getFingerPrint(), 2);
				simHashList.addAll(SimHashUtil.getSimHashList(pageContext.getFingerPrint(), 1));
				simHashList.add(pageContext.getFingerPrint());
				//从数据库中找出相似的网页, 并存相似网页的id
				pageContext.getSimilarFingerPrintIDs().clear();
				for (int i = 0; i < simHashList.size(); i++) {
					List<PageFingerPrint> list = simpleDPL.getByFingerPrint(simHashList.get(i));
					for (PageFingerPrint pp : list) {
						Tracer.info("找到相同id: " + pp.get_id());
						pageContext.getSimilarFingerPrintIDs().add(pp.get_id());
					}
				}

				//删除自身id
				pageContext.getSimilarFingerPrintIDs().remove(pageContext.get_id());

				//更新到mongo数据库中
				if (pageContext.getSimilarFingerPrintIDs().size() > 0) {
					CrawlPageContext query = new CrawlPageContext();
					query = new CrawlPageContext();
					query.set_id(pageContext.get_id());
					mongo.update(tableContext2, query, pageContext);
				}
			}
		} catch (Exception e) {
			Tracer.exception("线程: " + name + " 发生了异常");
			Tracer.exception(e);
		} finally {
			Tracer.info("线程: " + name + " 结束");
		}
	}

	@Override
	protected void handleMessage() {
	}
}

//
//
//
//
//
//
//
//
//
//
